﻿using Dapper.DBContext;
using Guoc.BigMall.Domain.Entity;
using Guoc.BigMall.Infrastructure;
using Guoc.BigMall.Infrastructure.Events;
using Guoc.BigMall.Infrastructure.Extension;
using Guoc.BigMall.Infrastructure.Payment;
using Guoc.BigMall.WebService.Event;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Guoc.BigMall.WebService.Implement
{
    public class PaymenService : IPaymentService
    {
        IDBContext _db;
        IEventPublisher _eventPublisher;
        public PaymenService(IDBContext dbContext, IEventPublisher eventPublisher)
        {
            this._db = dbContext;
            this._eventPublisher = eventPublisher;

        }

        public void Notify(AbstractRequest data)
        {
           
            if (data.Content["return_code"].ToString() == "FAIL") {
                throw new FriendlyException("微信支付回调通知失败:" + data.Content["return_msg"].ToString());
            }

            var orderCode = data.Content["out_trade_no"].ToString();
            
        }

        public void Notify(string content)
        {
            if (string.IsNullOrEmpty(content)) { 
                throw new FriendlyException("通知报文内容为空");
            }
            AbstractRequest data = new AbstractRequest();
            data.FromXml(content);

            if (data.Content["return_code"].ToString() == "FAIL"|| data.Content["result_code"].ToString() == "FAIL")
            {
                throw new FriendlyException("微信支付回调通知失败:" + data.Content["return_msg"].ToString());
            }
            var orderCode = data.Content["out_trade_no"].ToString();
            // 先校验是否已经支付过了 
            if (_db.Table<TransactionHistory>().Exists(n => n.TradeCode == orderCode && n.TradeKey == TradeKeyName.Wechat_Pay_Notify))
            {
                return;
            }

            var entity = _db.Table<SaleOrder>().FirstOrDefault(n => n.Code == orderCode);
            if (entity == null)
            {
                throw new FriendlyException("订单:{0} 不存在".FormatWith(orderCode));
            }
            entity.FinishPiad();
            TransactionHistory histroy = new TransactionHistory()
            {
                TradeType = TradeType.OrderPay,
                TradeKey = TradeKeyName.Wechat_Pay_Notify,
                TradeName = "微信支付通知",
                TradeCode = entity.Code,
                TradeAmount = entity.OrderAmount,
                OutTradeNo = data.Content["transaction_id"].ToString(),
                TradeContent = content,
                TradeDate = DateTime.ParseExact(data.Content["time_end"].ToString(), "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture)
        };

            _db.Update(entity);
            _db.Insert(histroy);
            _db.SaveChange();

            // 触发支付完成事件
            Task task = Task.Run(() =>
            {
                SaleOrderPaidEvent paidEvent = new SaleOrderPaidEvent()
                {
                    Order = entity
                };
                _eventPublisher.Publish(paidEvent);
            });
        }

        public void PaidNotify(string saleOrderCode)
        {
            //完成支付记录
            var entity = _db.Table<SaleOrder>().FirstOrDefault(n => n.Code == saleOrderCode);
            if (entity == null)
            {
                throw new FriendlyException("订单:{0} 不存在".FormatWith(saleOrderCode));
            }

            entity.FinishPiad();
            TransactionHistory histroy = new TransactionHistory()
            {
                TradeType = TradeType.OrderPay,
                TradeKey = "SaleOrder.Pay.Notify",
                TradeName = "销售单支付通知",
                TradeCode = entity.Code,
                TradeAmount = entity.OrderAmount,
                OutTradeNo = "",
                TradeContent = "process by admin",
            };

            _db.Update(entity);
            _db.Insert(histroy);
            _db.SaveChange();

            // 触发支付完成事件
            Task task = Task.Run(() =>
            {
                SaleOrderPaidEvent paidEvent = new SaleOrderPaidEvent()
                {
                    Order = entity
                };
                _eventPublisher.Publish(paidEvent);
            });
          
        }
    }
}
